<?php

/**
 * @author TUNAFISHIE
 */
class openinghours_model extends CI_Model {

    var $openingHours = array();

    function __construct() {
        parent::__construct();
    }
    
/*
|--------------------------------------------------------------------------
| parseTermXml (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| This function parses the opening hours xml and returns the final output for 
| the term opening hours module.
| 
| The output consist of:
|   1. The current term (today's date within the term's date range)
|   2. The following new term if today is 2 weeks before the start date of that term.
|   3. Special occasions (30 days in advance) 
|
*/ 
    function parseTermXml($xmlOpeningHoursUrl, $xmlSpecialOccasionUrl, $index) {
        $nextTermIndex = -1;
        $openingHoursInfo = array();

        $openingHoursData = simplexml_load_file($xmlOpeningHoursUrl);
        $specialOccasionData = simplexml_load_file($xmlSpecialOccasionUrl);
        //get today's date + 30 days and +14 days
        date_default_timezone_set('Asia/Singapore');
        $todayDate = $this->getTodayDate();
        $todayPlus14Days = $this->getTodayDateInAdvancedInUFormat("+14 day");

        //get special occasions
        $specialOccasions = $this->getSpecialOccasions($specialOccasionData);

        //total number of terms
        $termCount = count($openingHoursData->array->array[$index]->array);
        for ($i = 0; $i < $termCount; $i++) {
            $term = $openingHoursData->array->array[$index]->array[$i];

            //get start date of the term
            $termStartDateString = (string) $term->string[1];
            $termStartDate = $this->getDateInUFormat($termStartDateString);
            //get end date of the term
            $termEndDateString = (string) $term->string[2];
            $termEndDate = $this->getDateInUFormat($termEndDateString);

            $termDate = $termStartDateString . ' - ' . $termEndDateString;

            //check if today falls within the term's date range
            if ($todayDate <= $termEndDate) {
                ;
                //check if it's 2 weeks before the end of this term
                if ($termEndDate <= $todayPlus14Days) {
                    $nextTermIndex = $i + 1;
                }

                $locations = $this->getLocationsArray($term, $specialOccasions, $termStartDateString, $termEndDateString);

                //add current term to openinghoursinfo array                
                $openingHoursInfo[] = array('termDate' => $termDate, 'opLocations' => $locations);

                //process next term (if applicable)
                if ($nextTermIndex != -1) {
                    $locations = array();
                    $nextTerm = $openingHoursData->array->array[$index]->array[$nextTermIndex];

                    $termStartDateString = (string) $nextTerm->string[1];
                    $termEndDateString = (string) $nextTerm->string[2];
                    $termDate = $termStartDateString . ' - ' . $termEndDateString;

                    $locations = $this->getLocationsArray($nextTerm, $specialOccasions, $termStartDateString, $termEndDateString);

                    $openingHoursInfo[] = array('termDate' => $termDate, 'opLocations' => $locations);
                }
                break;
            }
        }

        $output = array('openingHoursInfo' => $openingHoursInfo);
        return $output;
    }
    
/*
|--------------------------------------------------------------------------
| getDateInUFormat (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Returns convert string to date in U format (timestamp)
|
*/ 
    function getDateInUFormat($termDateString) {
        //get start date of the term
        $termDate = new DateTime($termDateString);
        $termDate = $termDate->format('U');

        return $termDate;
    }
    
/*
|--------------------------------------------------------------------------
| getTodayDateInAdvancedInUFormat (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Returns modified current date in U format.
|
*/ 
    function getTodayDateInAdvancedInUFormat($modifyValue) {
        //get start date of the term
        $termDate = new DateTime();
        $termDate->modify($modifyValue);
        $termDate = $termDate->format('U');

        return $termDate;
    }
    
/*
|--------------------------------------------------------------------------
| getTodayDate (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Returns current date in U format.
|
*/
    function getTodayDate() {
        $termDate = new DateTime();
        $termDate = $termDate->format('U');

        return $termDate;
    }
    
/*
|--------------------------------------------------------------------------
| getDateInAdvancedInUFormat (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Convert string to date and returns modified date in U format.
|
*/
    function getDateInAdvancedInUFormat($dateString, $modifyValue) {
        $date = new DateTime($dateString);
        $date->modify($modifyValue);
        $date = $date->format('U');

        return $date;
    }
    
/*
|--------------------------------------------------------------------------
| checkIfFallsWithinDateRange (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Takes in the start and end date of a date range and check if the provided
| date falls within the date range.
|
*/
    function checkIfFallsWithinDateRange($startDateString, $endDateString, $dateToCheckString) {
        $startDate = $this->getDateInUFormat($startDateString);
        $endDate = $this->getDateInUFormat($endDateString);
        $dateToCheck = $this->getDateInUFormat($dateToCheckString);

        if ($startDate <= $dateToCheck && $endDate >= $dateToCheck) {
            return true;
        } else {
            return false;
        }
    }
    
/*
|--------------------------------------------------------------------------
| getLocationsArray (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Creates location objects using the term's details, start dae, end date 
| and special occasions info.
|
*/
    function getLocationsArray($term, $specialOccasions, $startDateString, $endDateString) {
        $termForLib = new openinghours_model();
        $termForLrc = new openinghours_model();

        //library
        $libraryData = $term->array[0];
        //count number of details
        $libDetailsCount = count($libraryData->array);
        for ($j = 0; $j < $libDetailsCount; $j++) {
            $libDetail = $libraryData->array[$j];
            $description = (string) $libDetail->string[0];
            $detail = (string) $libDetail->string[1];
            $termForLib->openingHours[] = array('description' => $description, 'detail' => $detail);
        }

        //lrc
        $lrcData = $term->array[1];
        //count number of details
        $lrcDetailsCount = count($lrcData->array);
        for ($j = 0; $j < $lrcDetailsCount; $j++) {
            $lrcDetail = $lrcData->array[$j];
            $description = (string) $lrcDetail->string[0];
            $detail = (string) $lrcDetail->string[1];
            $termForLrc->openingHours[] = array('description' => $description, 'detail' => $detail);
        }

        //add special occasions into term array
        $specialOccasionsCount = count($specialOccasions);
        for ($k = 0; $k < $specialOccasionsCount; $k++) {
            $specialOccasion = $specialOccasions[$k];

            //check if special occassion falls within date range
            $specialOccasionDate = $specialOccasion['date'];
            $result = $this->checkIfFallsWithinDateRange($startDateString, $endDateString, $specialOccasionDate);

            if ($result) {
                $termForLib->openingHours[] = array('description' => $specialOccasion['description'], 'detail' => $specialOccasion['detail']);
                $termForLrc->openingHours[] = array('description' => $specialOccasion['description'], 'detail' => $specialOccasion['detail']);
            }
        }

        //add to location array
        $locations[] = array(
            'locationName' => 'Library',
            'openingHours' => $termForLib->openingHours
        );

        $locations[] = array(
            'locationName' => 'Learning Resource Center',
            'openingHours' => $termForLrc->openingHours
        );

        return $locations;
    }
    
/*
|--------------------------------------------------------------------------
| getSpecialOccasions (@author : Justina Lee)
|--------------------------------------------------------------------------
|
| Returns special occassions that falls within 30 days.
|
*/
    function getSpecialOccasions($specialOccasionData) {
        $retOccasions = array();
        $todayDate = $this->getTodayDate();
        $todayPlus30Days = $this->getTodayDateInAdvancedInUFormat("+30 day");

        //total number of special occasions in xml file
        $specialOccasionCount = count($specialOccasionData->array->array);

        for ($i = 0; $i < $specialOccasionCount; $i++) {
            $specialOccasion = $specialOccasionData->array->array[$i];

            //get date of this ocassion
            $specialOccasionDateString = $specialOccasion->string[0];
            $specialOccasionDateMidnight = $this->getDateInUFormat($specialOccasionDateString);
            $specialOccasionDate = $this->getDateInAdvancedInUFormat($specialOccasionDateString, '+1 day');

            //check if special occassion has past
            if ($todayDate < $specialOccasionDate) {
                //check if within 30 days 
                if ($specialOccasionDateMidnight <= $todayPlus30Days) {
                    $description = $specialOccasion->string[1] . ' (' . $specialOccasionDateString . ')';
                    $detail = (string) $specialOccasion->string[2];

                    $retOccasions[] = array('description' => $description, 'detail' => $detail, 'date' => $specialOccasionDateString);
                }
            }
        }

        return $retOccasions;
    }

}
?>


